# Copyright 2009 Crisis Response International Inc.
# Derived from rietveld/codereview/views.py, Copyright 2008 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""Data models for mercyDMS."""

# Python imports
import logging
import re
import datetime

# AppEngine imports
from google.appengine.ext import db
from google.appengine.ext.db import polymodel
from google.appengine.api import memcache

# Local imports
from common.choices import *

### GQL query cache ###


_query_cache = {}


def gql(cls, clause, *args, **kwds):
  """Return a query object, from the cache if possible.

  Args:
    cls: a db.Model subclass.
    clause: a query clause, e.g. 'WHERE draft = TRUE'.
    *args, **kwds: positional and keyword arguments to be bound to the query.

  Returns:
    A db.GqlQuery instance corresponding to the query with *args and
    **kwds bound to the query.
  """
  query_string = 'SELECT * FROM %s %s' % (cls.kind(), clause)
  query = _query_cache.get(query_string)
  if query is None:
    _query_cache[query_string] = query = db.GqlQuery(query_string)
  query.bind(*args, **kwds)
  return query

class PrefSet(db.Model):
  pref_administration = db.BooleanProperty()
  pref_medical = db.BooleanProperty()
  pref_cleanup = db.BooleanProperty()
  pref_radio = db.BooleanProperty()
  pref_chaplaincy = db.BooleanProperty()
  pref_foodservice = db.BooleanProperty()
  pref_logistics = db.BooleanProperty()
  pref_crihop = db.BooleanProperty()
  pref_rescue = db.BooleanProperty()

class SkillSet(db.Model):
  skill_carpentry = db.StringProperty()
  skill_maintenance = db.StringProperty()
  skill_clergy = db.StringProperty()
  skill_mechanic = db.StringProperty()
  skill_clerical = db.StringProperty()
  skill_mental = db.StringProperty()
  skill_computer = db.StringProperty()
  skill_nurse = db.StringProperty()
  skill_doctor = db.StringProperty()
  skill_office = db.StringProperty()
  skill_admin_assist = db.StringProperty()
  skill_electrician = db.StringProperty()
  skill_photographer = db.StringProperty()
  skill_medtech = db.StringProperty()
  skill_plumber = db.StringProperty()
  skill_cooking = db.StringProperty()
  skill_security = db.StringProperty()
  skill_forklift = db.StringProperty()
  skill_socialserv = db.StringProperty()
  skill_HVAC = db.StringProperty()
  skill_teacher = db.StringProperty()
  skill_internet = db.StringProperty()
  skill_programming = db.StringProperty()
  skill_video = db.StringProperty()
  skill_journalism = db.StringProperty()
  skill_warehouse = db.StringProperty()
  skill_radio_cert_level = db.StringProperty()
  skill_radio_license_yr = db.StringProperty()

  skill_guitar_acoustic = db.StringProperty()
  skill_guitar_electric = db.StringProperty()
  skill_guitar_bass = db.StringProperty()
  skill_drums = db.StringProperty()
  skill_keyboard = db.StringProperty()
  skill_percussion = db.StringProperty()
  skill_vocals = db.StringProperty()
  skill_minister = db.StringProperty()
  skill_chaplain = db.StringProperty()
  skill_instrument_def = db.StringProperty()
  skill_instrument_level = db.StringProperty()
  skill_worship_ministry_exp = db.TextProperty()

  skill_license = db.TextProperty()
  skill_language1 = db.StringProperty()
  skill_lanlevel1 = db.StringProperty()
  skill_language2 = db.StringProperty()
  skill_lanlevel2 = db.StringProperty()
  skill_language3 = db.StringProperty()
  skill_lanlevel3 = db.StringProperty()
  skill_language4 = db.StringProperty()
  skill_lanlevel4 = db.StringProperty()
  skill_lan_other_def1 = db.StringProperty()
  skill_lan_other_level1 = db.StringProperty()
  skill_lan_other_def2 = db.StringProperty()
  skill_lan_other_level2 = db.StringProperty()

class CourseSet(db.Model):
  """Courses taken by volunteers
  """
  cridrt = db.BooleanProperty()
  fema100 = db.BooleanProperty()
  fema200 = db.BooleanProperty()
  fema700 = db.BooleanProperty()
  fema800 = db.BooleanProperty()

class Person(db.Model):
  """A person
  """
  title = db.StringProperty()
  fname = db.StringProperty(required=True)
  mname = db.StringProperty()
  lname = db.StringProperty(required=True)
  gender = db.StringProperty()
  dob = db.DateProperty()
  address = db.StringProperty()
  city = db.StringProperty()
  state = db.StringProperty()
  zipcode = db.StringProperty()
  email = db.EmailProperty()
  email2 = db.StringProperty()
  hphone = db.StringProperty()
  wphone = db.StringProperty()
  cphone = db.StringProperty()
  aphone = db.StringProperty()


class Volunteer(Person):
  """A volunteer who is registered to respond.
  """
  user = db.UserProperty(required=True)
  user_id = db.StringProperty(required=True)
  employment = db.StringProperty()
  occupation = db.StringProperty()
  notification = db.StringProperty()
  active = db.BooleanProperty()
  current_vol_act = db.TextProperty()
  driver_state = db.StringProperty()
  driver_class = db.StringProperty()
  have_passport = db.BooleanProperty()
  passport_date = db.StringProperty()
  out_of_country_avail = db.BooleanProperty()
  would_receive_info = db.BooleanProperty()
  deploy_availability = db.ListProperty(datetime.datetime)
  prefset = db.ReferenceProperty(PrefSet, collection_name="task_preferences")
  skillset = db.ReferenceProperty(SkillSet, collection_name="skills")
  courseset = db.ReferenceProperty(CourseSet, collection_name="courses")
  skills_approved = db.BooleanProperty() # skill have been reviewed and approved
  skills_approved_by = db.ReferenceProperty(Person, collection_name="skill_approvers")
  med_approved = db.BooleanProperty()              # medically approved for deployment
  med_approved_by = db.ReferenceProperty(Person, collection_name="med_approvers")
  spiritual_approved = db.BooleanProperty()           # spiritually/emotionally approved for deployment
  spiritual_approved_by = db.ReferenceProperty(Person, collection_name="spiritual_approvers")
  courses_approved = db.BooleanProperty()
  courses_approved_by = db.ReferenceProperty(Person, collection_name="courses_approvers")
  emergency_contact = db.ReferenceProperty(Person, collection_name="emergency_contacts")
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)


def get_volunteer_by_user_id(user_id):
  """ Fetches a volunteer by their user id.

  Args:
    user_id: The user id of the Volunteer to fetch.

  Returns:
    The models.Volunteer object corresponding with the unique user id, or None
    if no user was found.
  """
  querystr = 'where user_id = ' + str(user_id)
  return gql(Volunteer, 'where user_id = :1', user_id).get()

